package com.ruoyi.common.utils.sign;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.util.StringUtils;

import java.util.*;

public class Sign {

    // 秘钥
    static final String SECRET = "ZWZvb2QyMDIw";
    // 签名是有谁生成
    static final String ISSUSER = "EFOOD";
    // 签名的主题
    static final String SUBJECT = "EFOOD API TOKEN";
    // 签名的观众
    static final String AUDIENCE = "EFOOD WXMP";

    public static final String CLAIM_USER_ID = "userId";

    public static final String TAG = "tag";


    public static String createToken(Long userId,String tag) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            Map<String, Object> map = new HashMap<String, Object>();
            Date nowDate = new Date();
            // 过期时间：1个月
            Date expireDate = getAfterDate(nowDate, 0, 1, 0, 0, 0, 0);
            map.put("alg", "HS256");
            map.put("typ", "JWT");
            JWTCreator.Builder builder = JWT.create();
            if (tag != null){
                builder.withClaim(TAG,tag);
            }
            String token = builder
                    // 设置头部信息 Header
                    .withHeader(map)
                    // 设置 载荷 Payload
                    .withClaim(CLAIM_USER_ID, userId)
                    .withIssuer(ISSUSER)
                    .withSubject(SUBJECT)
                    .withAudience(AUDIENCE)
                    // 生成签名的时间
                    .withIssuedAt(nowDate)
                    // 签名过期的时间
                    .withExpiresAt(expireDate)
                    // 签名 Signature
                    .sign(algorithm);
            return token;
        } catch (JWTCreationException exception) {
            exception.printStackTrace();
        }
        return null;
    }

    public static Map<String,Object> verifyTokenAndGetUserId(String token) {
        Map<String,Object> result = new HashMap<>();
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(ISSUSER)
                    .build();
            if (StringUtils.hasLength(token)) {
                DecodedJWT jwt = verifier.verify(token);
                Map<String, Claim> claims = jwt.getClaims();
                Claim claim = claims.get(CLAIM_USER_ID);
                Claim claim1 = claims.get(TAG);
                result.put(CLAIM_USER_ID,claim.asLong());
                result.put(TAG,claim1!=null?claim1.asString():null);
                return result;
            }
        } catch (JWTVerificationException exception) {
            exception.printStackTrace();
        }
        return result;
    }

    public static Date getAfterDate(Date date, int year, int month, int day, int hour, int minute, int second) {
        if (date == null) {
            date = new Date();
        }

        Calendar cal = new GregorianCalendar();

        cal.setTime(date);
        if (year != 0) {
            cal.add(Calendar.YEAR, year);
        }
        if (month != 0) {
            cal.add(Calendar.MONTH, month);
        }
        if (day != 0) {
            cal.add(Calendar.DATE, day);
        }
        if (hour != 0) {
            cal.add(Calendar.HOUR_OF_DAY, hour);
        }
        if (minute != 0) {
            cal.add(Calendar.MINUTE, minute);
        }
        if (second != 0) {
            cal.add(Calendar.SECOND, second);
        }
        return cal.getTime();
    }

}
